package map.tile.server.common;

import java.io.*;
import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.Inflater;

/**
 * 只能单线程使用
 */
public final class ObjZip {

    Deflater deflater;
    Inflater inflater;
    GZIPOutputStream gzipOutputStream;
    GZIPInputStream gzipInputStream;
    ByteArrayInputStream byteArrayInputStream;
    ObjectInputStream objectInputStream;
    ByteArrayOutputStream byteArrayOutputStream;
    ObjectOutputStream objectOutputStream;

    /**
     * @param inputByte 待解压缩的字节数组
     * @return 解压缩后的字节数组
     * @throws IOException
     */
    public byte[] deflateUnZip(byte[] inputByte) {
        if (inputByte == null) return null;
        int len = 0;
        inflater = new Inflater();
        inflater.setInput(inputByte);
        byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] outByte = new byte[1024];
        try {
            while (!inflater.finished()) {
                // 解压缩并将解压缩后的内容输出到字节输出流bos中
                len = inflater.inflate(outByte);
                if (len == 0) {
                    break;
                }
                byteArrayOutputStream.write(outByte, 0, len);
            }
            inflater.end();
        } catch (Exception e) {
        } finally {
            try {
                byteArrayOutputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return byteArrayOutputStream.toByteArray();
    }

    /**
     * 压缩.
     *
     * @param inputByte 待压缩的字节数组
     * @return 压缩后的数据
     * @throws IOException
     */
    public byte[] deflateZip(byte[] inputByte) {
        if (inputByte == null) return null;
        int len = 0;
        deflater = new Deflater();
        deflater.setInput(inputByte);
        deflater.finish();
        byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] outputByte = new byte[1024];
        try {
            while (!deflater.finished()) {
                // 压缩并将压缩后的内容输出到字节输出流bos中
                len = deflater.deflate(outputByte);
                byteArrayOutputStream.write(outputByte, 0, len);
            }
            deflater.end();
        } finally {
            try {
                byteArrayOutputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return byteArrayOutputStream.toByteArray();
    }

    public byte[] gZip(byte[] data) {
        if (data == null) return null;
        if (data.length == 0) return data;
        byte[] ret = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
            gzipOutputStream.write(data);
            gzipOutputStream.finish();
            gzipOutputStream.close();
            ret = byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                byteArrayOutputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ret;
        }
    }

    public byte[] gUnZip(byte[] data) {
        if (data == null) return null;
        byte[] ret = null;
        try {
            byteArrayInputStream = new ByteArrayInputStream(data);
            gzipInputStream = new GZIPInputStream(byteArrayInputStream);
            byte[] buf = new byte[1024];
            int num = -1;
            byteArrayOutputStream = new ByteArrayOutputStream();
            while ((num = gzipInputStream.read(buf, 0, buf.length)) != -1) {
                byteArrayOutputStream.write(buf, 0, num);
            }
            ret = byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                gzipInputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                byteArrayInputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                byteArrayOutputStream.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                byteArrayOutputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ret;
        }
    }


    public Object byteToObj(byte[] bytes) {
        Object obj = null;
        try {
            byteArrayInputStream = new ByteArrayInputStream(bytes);
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            obj = objectInputStream.readObject();
            byteArrayInputStream.close();
            objectInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }


    public byte[] objToByte(Object obj) {
        byte[] bytes = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(obj);
            bytes = byteArrayOutputStream.toByteArray();
            byteArrayOutputStream.close();
            objectOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bytes;
    }
}
